import os
import datetime
from typing import Optional, Tuple
from PyQt5.QtWidgets import (
    QDialog, QVBoxLayout, QHBoxLayout, QGroupBox, QFormLayout,
    QCheckBox, QSpinBox, QComboBox, QPushButton, QLabel, QLineEdit,
    QDateTimeEdit, QMessageBox, QTextEdit
)
from PyQt5.QtCore import QSettings, QDateTime, Qt
from PyQt5.QtGui import QFont

# 导入配置和工具
from config.constants import (
    DEFAULT_RECORD_FPS, DEFAULT_LOG_LEVEL, DEFAULT_LOG_KEEP_DAYS,
    REQUIRED_LIBS
)
from utils.helper import logger, check_script_syntax, check_script_dependencies
from db.operations import load_scripts, get_script_by_id


# -------------------------- 系统设置对话框 --------------------------
class SettingsDialog(QDialog):
    """系统设置对话框（录屏、日志、脚本检查配置）"""
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("系统设置")
        self.setMinimumWidth(500)
        self.setWindowModality(Qt.ApplicationModal)  # 模态对话框
        self.settings = QSettings("RPAManager", "Settings")  # 存储在系统注册表
        self.init_ui()

    def init_ui(self):
        """初始化UI布局"""
        main_layout = QVBoxLayout(self)

        # 1. 录屏设置分组
        record_group = QGroupBox("📹 录屏设置")
        record_layout = QFormLayout(record_group)

        # 1.1 默认启用录屏
        self.record_enabled = QCheckBox()
        self.record_enabled.setChecked(self.settings.value("recording/enabled", True, type=bool))
        record_layout.addRow("默认启用录屏", self.record_enabled)

        # 1.2 录屏帧率
        self.fps_spin = QSpinBox()
        self.fps_spin.setRange(1, 30)  # 帧率范围：1-30FPS
        self.fps_spin.setValue(self.settings.value("recording/fps", DEFAULT_RECORD_FPS, type=int))
        record_layout.addRow("录屏帧率（FPS）", self.fps_spin)

        main_layout.addWidget(record_group)

        # 2. 日志设置分组
        log_group = QGroupBox("📝 日志设置")
        log_layout = QFormLayout(log_group)

        # 2.1 日志级别
        self.log_level = QComboBox()
        log_levels = ["DEBUG", "INFO", "WARNING", "ERROR"]
        self.log_level.addItems(log_levels)
        # 设置默认值（从配置或保存的设置中获取）
        saved_level = self.settings.value("logging/level", DEFAULT_LOG_LEVEL)
        self.log_level.setCurrentText(saved_level if saved_level in log_levels else DEFAULT_LOG_LEVEL)
        log_layout.addRow("日志级别", self.log_level)

        # 2.2 日志保留天数
        self.log_keep_days = QSpinBox()
        self.log_keep_days.setRange(7, 365)  # 保留7-365天
        self.log_keep_days.setValue(self.settings.value("logging/keep_days", DEFAULT_LOG_KEEP_DAYS, type=int))
        log_layout.addRow("日志保留天数", self.log_keep_days)

        # 2.3 清理过期日志按钮
        self.clear_log_btn = QPushButton("清理过期日志")
        self.clear_log_btn.clicked.connect(self.clear_expired_logs)
        log_layout.addRow(self.clear_log_btn)

        main_layout.addWidget(log_group)

        # 3. 脚本检查设置分组
        script_group = QGroupBox("📜 脚本检查设置")
        script_layout = QFormLayout(script_group)

        # 3.1 自动检查语法
        self.check_syntax = QCheckBox()
        self.check_syntax.setChecked(self.settings.value("script/check_syntax", True, type=bool))
        script_layout.addRow("添加脚本时自动检查语法", self.check_syntax)

        # 3.2 自动检查依赖
        self.check_deps = QCheckBox()
        self.check_deps.setChecked(self.settings.value("script/check_deps", True, type=bool))
        script_layout.addRow("添加脚本时自动检查依赖", self.check_deps)

        main_layout.addWidget(script_group)

        # 4. 按钮区域（确认/取消）
        btn_layout = QHBoxLayout()
        self.ok_btn = QPushButton("确认")
        self.ok_btn.clicked.connect(self.accept)
        self.cancel_btn = QPushButton("取消")
        self.cancel_btn.clicked.connect(self.reject)
        btn_layout.addWidget(self.ok_btn)
        btn_layout.addWidget(self.cancel_btn)
        main_layout.addLayout(btn_layout)

    def clear_expired_logs(self):
        """清理过期日志（调用工具函数）"""
        from utils.helper import clear_expired_logs  # 避免循环导入
        try:
            # 使用当前设置的保留天数
            keep_days = self.log_keep_days.value()
            deleted_logs, deleted_recordings = clear_expired_logs(keep_days)
            msg = (f"清理完成！\n"
                   f"- 删除过期日志：{deleted_logs} 条\n"
                   f"- 删除过期录屏：{deleted_recordings} 个文件")
            QMessageBox.information(self, "清理成功", msg)
        except Exception as e:
            QMessageBox.critical(self, "清理失败", f"清理过期日志时出错：{str(e)}")

    def accept(self):
        """保存设置并关闭对话框"""
        # 保存录屏设置
        self.settings.setValue("recording/enabled", self.record_enabled.isChecked())
        self.settings.setValue("recording/fps", self.fps_spin.value())

        # 保存日志设置
        self.settings.setValue("logging/level", self.log_level.currentText())
        self.settings.setValue("logging/keep_days", self.log_keep_days.value())

        # 保存脚本检查设置
        self.settings.setValue("script/check_syntax", self.check_syntax.isChecked())
        self.settings.setValue("script/check_deps", self.check_deps.isChecked())

        logger.info("系统设置已更新")
        QMessageBox.information(self, "保存成功", "系统设置已生效")
        super().accept()


# -------------------------- 任务创建/编辑对话框 --------------------------
class TaskDialog(QDialog):
    """任务创建或编辑对话框（配置任务名称、关联脚本、Cron表达式等）"""
    def __init__(self, task_id: Optional[int] = None, parent=None):
        super().__init__(parent)
        self.task_id = task_id  # None表示新建，否则为编辑
        self.setWindowTitle("编辑任务" if task_id else "创建任务")
        self.setMinimumWidth(550)
        self.setWindowModality(Qt.ApplicationModal)
        self.settings = QSettings("RPAManager", "Settings")  # 复用系统设置
        self.init_ui()

    def init_ui(self):
        """初始化UI布局"""
        main_layout = QVBoxLayout(self)

        # 1. 基本信息分组
        basic_group = QGroupBox("基本信息")
        basic_layout = QFormLayout(basic_group)

        # 1.1 任务名称
        self.name_edit = QLineEdit()
        self.name_edit.setPlaceholderText("请输入任务名称（如：每日数据同步）")
        basic_layout.addRow("任务名称*", self.name_edit)

        # 1.2 关联脚本
        self.script_combo = QComboBox()
        self.script_combo.setMinimumWidth(300)
        self.refresh_scripts()  # 加载脚本列表
        # 刷新脚本按钮
        refresh_btn = QPushButton("刷新")
        refresh_btn.clicked.connect(self.refresh_scripts)
        # 组合布局（下拉框+刷新按钮）
        script_layout = QHBoxLayout()
        script_layout.addWidget(self.script_combo)
        script_layout.addWidget(refresh_btn)
        basic_layout.addRow("关联脚本*", script_layout)

        main_layout.addWidget(basic_group)

        # 2. 定时设置分组
        cron_group = QGroupBox("定时设置（Cron表达式）")
        cron_layout = QFormLayout(cron_group)

        # 2.1 Cron表达式输入
        self.cron_edit = QLineEdit()
        self.cron_edit.setPlaceholderText("格式：分 时 日 月 周（示例：0 8 * * 1 表示每周一8:00）")
        cron_layout.addRow("Cron表达式*", self.cron_edit)

        # 2.2 Cron格式说明
        cron_help = QLabel(
            "<small><b>格式说明：</b>分(0-59) 时(0-23) 日(1-31) 月(1-12) 周(0-6, 0=周一)<br>"
            "特殊符号：* 表示所有值（如* * * * * 表示每分钟）</small>"
        )
        cron_help.setTextInteractionFlags(Qt.TextSelectableByMouse)
        cron_layout.addRow(cron_help)

        main_layout.addWidget(cron_group)

        # 3. 执行设置分组
        exec_group = QGroupBox("执行设置")
        exec_layout = QFormLayout(exec_group)

        # 3.1 启用任务
        self.enabled_check = QCheckBox()
        self.enabled_check.setChecked(True)  # 默认启用
        exec_layout.addRow("启用任务", self.enabled_check)

        # 3.2 录屏设置
        self.record_check = QCheckBox()
        # 默认值从系统设置获取
        self.record_check.setChecked(self.settings.value("recording/enabled", True, type=bool))
        exec_layout.addRow("执行时录屏", self.record_check)

        # 3.3 日志级别
        self.log_level = QComboBox()
        self.log_level.addItems(["DEBUG", "INFO", "WARNING", "ERROR"])
        self.log_level.setCurrentText(DEFAULT_LOG_LEVEL)
        exec_layout.addRow("日志级别", self.log_level)

        main_layout.addWidget(exec_group)

        # 4. 按钮区域
        btn_layout = QHBoxLayout()
        self.preview_btn = QPushButton("预览下次运行时间")
        self.preview_btn.clicked.connect(self.preview_next_run)
        self.ok_btn = QPushButton("确认")
        self.ok_btn.clicked.connect(self.validate_and_accept)
        self.cancel_btn = QPushButton("取消")
        self.cancel_btn.clicked.connect(self.reject)
        btn_layout.addWidget(self.preview_btn)
        btn_layout.addWidget(self.ok_btn)
        btn_layout.addWidget(self.cancel_btn)
        main_layout.addLayout(btn_layout)

        # 如果是编辑任务，加载现有数据
        if self.task_id:
            self.load_task_data()

    def refresh_scripts(self):
        """刷新脚本下拉列表"""
        self.script_combo.clear()
        scripts = load_scripts()
        if not scripts:
            self.script_combo.addItem("暂无脚本，请先添加脚本")
            self.script_combo.setEnabled(False)
        else:
            for script in scripts:
                # 显示：脚本名称 (ID:xxx)
                self.script_combo.addItem(f"{script['name']} (ID:{script['id']})", script['id'])
            self.script_combo.setEnabled(True)

    def load_task_data(self):
        """加载任务数据到表单（编辑模式）"""
        from db.operations import get_task_by_id  # 避免循环导入
        task = get_task_by_id(self.task_id)
        if not task:
            QMessageBox.critical(self, "错误", f"任务ID={self.task_id}不存在")
            self.reject()
            return

        # 填充表单
        self.name_edit.setText(task['name'])
        # 选中关联脚本
        script_idx = self.script_combo.findData(task['script_id'])
        if script_idx >= 0:
            self.script_combo.setCurrentIndex(script_idx)
        self.cron_edit.setText(task['cron_expression'])
        self.enabled_check.setChecked(task['is_enabled'] == 1)
        self.record_check.setChecked(task['record_screen'] == 1)
        self.log_level.setCurrentText(task['log_level'])

    def preview_next_run(self):
        """预览Cron表达式的下次运行时间"""
        cron_expr = self.cron_edit.text().strip()
        if not cron_expr:
            QMessageBox.warning(self, "提示", "请先输入Cron表达式")
            return

        from utils.helper import calculate_next_run  # 避免循环导入
        next_run = calculate_next_run(cron_expr)
        if next_run:
            QMessageBox.information(self, "下次运行时间", f"根据Cron表达式计算：\n{next_run}")
        else:
            QMessageBox.warning(self, "计算失败", "无法解析Cron表达式，请检查格式")

    def validate_and_accept(self):
        """验证表单并提交"""
        # 1. 基本验证
        name = self.name_edit.text().strip()
        if not name:
            QMessageBox.warning(self, "验证失败", "任务名称不能为空")
            return

        script_id = self.script_combo.currentData()
        if script_id is None:
            QMessageBox.warning(self, "验证失败", "请选择关联脚本")
            return

        cron_expr = self.cron_edit.text().strip()
        if not cron_expr:
            QMessageBox.warning(self, "验证失败", "Cron表达式不能为空")
            return

        # 2. 简单验证Cron格式（5个部分）
        if len(cron_expr.split()) != 5:
            QMessageBox.warning(self, "验证失败", "Cron表达式格式错误（需5个部分：分 时 日 月 周）")
            return

        # 3. 验证通过，关闭对话框并返回数据
        self.accept()

    def get_task_data(self) -> dict:
        """获取表单数据（供调用方使用）"""
        return {
            "name": self.name_edit.text().strip(),
            "script_id": self.script_combo.currentData(),
            "cron_expression": self.cron_edit.text().strip(),
            "is_enabled": self.enabled_check.isChecked(),
            "record_screen": self.record_check.isChecked(),
            "log_level": self.log_level.currentText()
        }


# -------------------------- 关于对话框 --------------------------
class AboutDialog(QDialog):
    """关于对话框（显示软件信息、版本、依赖等）"""
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("关于 RPA 自动化管理工具")
        self.setMinimumWidth(400)
        self.setWindowModality(Qt.ApplicationModal)
        self.init_ui()

    def init_ui(self):
        """初始化UI布局"""
        main_layout = QVBoxLayout(self)

        # 1. 软件信息
        info_text = QTextEdit()
        info_text.setReadOnly(True)
        info_text.setHtml("""
        <h3 align="center">RPA 自动化管理工具</h3>
        <p align="center">版本：1.0.0</p>
        <p>功能说明：</p>
        <ul>
            <li>脚本管理：添加、编辑、删除Python自动化脚本</li>
            <li>任务调度：基于Cron表达式的定时任务管理</li>
            <li>执行监控：实时查看任务执行日志，支持屏幕录制</li>
            <li>日志管理：自动记录任务执行历史，支持过期清理</li>
        </ul>
        <p>依赖库：</p>
        """)
        # 添加依赖库列表
        for imp_name, pip_name in REQUIRED_LIBS:
            info_text.append(f"- {imp_name} (安装：pip install {pip_name})")

        main_layout.addWidget(info_text)

        # 2. 关闭按钮
        close_btn = QPushButton("关闭")
        close_btn.clicked.connect(self.accept)
        main_layout.addWidget(close_btn, alignment=Qt.AlignCenter)